// 用接口interface定义对象

interface list {
  id: number;
  name: string;
  // 第三种方式：字符串索引签名，签名的格式是这样的我们在[]中括号中定义一个`x`它的返回值类型是 any 这就是一个字符串索引签名，
  // 它的含义就是用任意字符串去索引list可以得到任意的结果，这样list就可以支持多个属性了
  [x: string]: any;
}

interface Result {
  data: list[];
}

function render(result: Result) {
  result.data.forEach((value) => {
    console.log(value.id, value.name);
  });
}

// 第一种方式：

let result = {
  data: [
    { id: 1, name: "A", sex: "male" }, // 传入多余的字段也可以通过类型检查`鸭式辨型`
    { id: 2, name: "B" },
  ],
};

render(result);

// 如果这样直接传入对象字面量则不行【没有定义`字符串索引签名`】
/* render({
  data: [
    {id: 1, name: 'A', sex: 'male'}, // 此处会报错`“sex”不在类型“list”中`
    {id: 2, name: 'B'}
  ]
}) */

// 定义了`字符串索引签名`
render({
  data: [
    { id: 1, name: "A", sex: "male", like: "apple" },
    { id: 2, name: "B", age: 18 },
  ],
});

// 第二种方式：

// 使用对象类型断言可以通过类型检查
render({
  data: [
    { id: 1, name: "C", sex: "woman" }, // 此处不会报错
    { id: 2, name: "D" },
  ],
} as Result); // 对象类型断言就是我们要明确的告诉编译器我们知道这个对象的类型就是 Result 这样编译器就会绕过类型检查

render(<Result>{
  data: [
    { id: 1, name: "C", sex: "woman" }, // 此处不会报错
    { id: 2, name: "D" },
  ],
}); // 对象类型断言除了可以用 as 来写，还可以写`<Result>` 但建议还是使用 as，因为第二种`<Result>`在React中会存在歧义

export {};
